<!DOCTYPE HTML>
<html>
<head>
<title>Loop (注册表) | AutoHotkey</title>
<meta name="description" content="The Loop Reg statement retrieves the contents of the specified registry subkey, one item at a time." />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/theme.css" rel="stylesheet" type="text/css" />
<script src="../static/content.js" type="text/javascript"></script>
</head>
<body>

<h1>Loop (注册表)</h1>
<p>获取指定的注册表子键的内容,每次一个项目.</p>

<h2 id="new">新语法 <span class="ver">[v1.1.21+]</span></h2>
<pre class="Syntax"><span class="func">Loop, Reg</span>, KeyName <span class="optional">, Mode</span></pre>

<h3>参数</h3>
<dl>

  <dt>Reg</dt>
  <dd><p>原义单词 <code>Reg</code>(不区分大小写), 不可用变量或表达式.</p></dd>

  <dt>KeyName</dt>
  <dd><p>注册表键的全名, 如 <code>HKLM\Software</code> 或 <code>%FullPathOfKey%</code>.</p>
      <p>必须以 HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CURRENT_USER, HKEY_CLASSES_ROOT 或 HKEY_CURRENT_CONFIG(或这些的缩写, 如 HKLM) 开始. 要访问<a href="#remote">远程注册表</a>, 请在前面加上计算机名和冒号, 就像在本例中一样: \\workstation01:HKEY_LOCAL_MACHINE</p></dd>

  <dt>Mode</dt>
  <dd><p>零个或多个下列字母:</p>
      <p><code>K</code>: 包含键名.<br>
      <code>V</code>: 包含键值. K 和 V 都被省略时, 默认包含键值.<br>
      <code>R</code>: 递归子键. 若省略 R, <em>KeyName</em> 下的子键中的键名和键值都不会被包含.</p></dd>

</dl>

<h2 id="old">传统语法</h2>
<p class="warning"><strong>不推荐:</strong> 不推荐在新脚本中使用此语法. 而是使用<a href="#new">新语法</a>.</p>
<pre class="Syntax"><span class="func">Loop</span>, RootKey <span class="optional">, Key, IncludeSubkeys?, Recurse?</span></pre>

<h3>参数</h3>
<dl>

  <dt>RootKey</dt>
  <dd><p>必须为 HKEY_LOCAL_MACHINE(或 HKLM), HKEY_USERS(或 HKU), HKEY_CURRENT_USER(或 HKCU), HKEY_CLASSES_ROOT(或 HKCR) 或 HKEY_CURRENT_CONFIG(或 HKCC) 的其中一个.</p>
      <p>要访问<a href="#remote">远程注册表</a>, 请在前面加上计算机名和冒号, 例如: \\workstation01:HKEY_LOCAL_MACHINE</p></dd>

  <dt>Key</dt>
  <dd><p>键名(例如 Software\SomeApplication). 如果为空或省略, 将获取 <em>根键</em> 的内容.</p></dd>
  
  <dt>IncludeSubkeys?</dt>
  <dd><p>0(默认值) 不获取 <em>Key</em> 中包含的子键(仅获取值).<br>
      1 获取所有的值和子键.<br>
      2 仅获取子键 (不获取值).</p></dd>

  <dt>Recurse?(递归?)</dt>
  <dd>0(默认值) 不对子键进行递归.<br>
      1 对子键进行递归, 以便获取包含在其中的所有值和子键.</dd>

</dl>

<h2>备注</h2>
<p>当您想对注册表值或子键集合中的项逐个进行操作时, 注册表循环很有用. 值和子键以逆序获取(自下而上), 这样在循环中使用 <a href="RegDelete.htm">RegDelete</a> 不会扰乱循环自身.</p>
<p id="vars">下列变量存在于任何注册表循环中.如果一个内层注册表循环包含在一个外层注册表循环中,那么最内层循环的注册表项将具有优先权:</p>
<table class="info">
  <tr>
    <td>A_LoopRegName</td>
    <td>当前获取项的名称, 可以是值名或子键名. 在 Windows 注册表编辑器中, 值名为 "(默认)" 的项如果分配了值,  那么也会获取它的值, 不过此时相应的 A_LoopRegName 将是空的.</td>
  </tr>
  <tr>
    <td>A_LoopRegType</td>
    <td>当前获取项的类型, 可以是下列单词的其中一个: KEY(即当前获取项为子键而不是值), REG_SZ, REG_EXPAND_SZ, REG_MULTI_SZ, REG_DWORD, REG_QWORD, REG_BINARY, REG_LINK, REG_RESOURCE_LIST, REG_FULL_RESOURCE_DESCRIPTOR, REG_RESOURCE_REQUIREMENTS_LIST, REG_DWORD_BIG_ENDIAN(在大多数 Windows 硬件上相当罕见). 如果当前获取项为未知类型, 那么此变量将为空.</td>
  </tr>
  <tr>
    <td>A_LoopRegKey</td>
    <td>正在访问的根键名(HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CURRENT_USER, HKEY_CLASSES_ROOT 或 HKEY_CURRENT_CONFIG). 访问远程注册表时, 此变量的值将<strong>不</strong>包含计算机名.</td>
  </tr>
  <tr>
    <td>A_LoopRegSubKey</td>
    <td>当前子键名. 如果没有使用 <em>Recurse</em> 参数以递归查询其他子键时, 此变量的值与 <em>Key</em> 参数相同. 在递归查询时, 此变量的值将为当前获取项的完整路径, 其中不包含根键. 例如: Software\SomeApplication\My SubKey</td>
  </tr>
  <tr>
    <td>A_LoopRegTimeModified</td>
    <td>当前子键或其中任何一个值的上次修改时间. 格式为 <a href="FileSetTime.htm">YYYYMMDDHH24MISS</a>. 当前获取项不是子键(即 <em>A_LoopRegType</em> 不是单词 KEY) 时,此变量将为空.</td>
  </tr>
</table>
<p>在注册表循环中使用下列命令时, 可以以一种简化的方式来操作当前获取项:</p>
<table class="info">
  <tr>
    <td style="width:21%"><a href="RegRead.htm">RegRead</a>, OutputVar</td>
    <td>读取当前项. 如果当前项为键, ErrorLevel 将被置为 1 且 <em>OutputVar</em> 将被置空.</td>
  </tr>
  <tr>
    <td><a href="RegWrite.htm">RegWrite</a> [, Value]</td>
    <td>写入到当前项. 如果省略 <em>Value</em>, 根据不同的类型当前项可能被置为 0 或空. 如果当前项为键, ErrorLevel 将被置为 1 且没有其他效果.</td>
  </tr>
  <tr>
    <td><a href="RegDelete.htm">RegDelete</a></td>
    <td>删除当前项. 如果当前项为键, 它以及它所包含的所有子键和值都将被删除.</td>
  </tr>
</table>
<p id="remote">访问远程注册表时(通过上面描述的 <em>RootKey</em> 或 <em>KeyName</em> 参数), 需要注意以下事项:</p>
<ul>
  <li>目标机器上必须正在运行远程注册表服务.</li>
  <li>如果您和目标计算机不在相同的域或者本地或远程用户名缺乏足够的权限(然而,请参阅下文了解可能的解决方法) 时,访问远程注册表可能失败.</li>
  <li>在尝试访问远程注册表之前, 根据您的用户名所在的域, 工作组和/或权限, 您可能必须连接到共享设备, 例如通过映射驱动器. 建立这样的连接 -- 使用拥有访问或编辑注册表权限的远程用户名和密码 -- 也许可以顺带启用远程注册表访问.</li>
  <li>如果您已经作为另一个用户连接到目标计算机(例如, 通过 Guest 用户映射驱动器), 您可能必须终止这个连接, 以允许远程注册表功能使用您当前登录的用户名重新连接和认证.</li>
  <li>对于 Windows Server 2003 和 Windows XP 专业版, MSDN 中声明: "如果 [注册表服务器] 所在的计算机加入了工作组且启用了 <em>强制以本地账户的来宾身份进行网络登录验证</em> 策略, 此功能无效. 请注意如果计算机加入了工作组, 那么这项策略默认是启用的."</li>
  <li>对于 Windows XP 家庭版, MSDN 中声明 "此功能总是无效". 家庭版没有注册表服务器和客户端, 尽管客户端可以从操作系统的某个 cab 压缩包提取.</li>
</ul>
<p>请参阅 <a href="Loop.htm">Loop</a> 了解关于<a href="Block.htm">区块</a>, <a href="Break.htm">Break</a>, <a href="Continue.htm">Continue</a> 和 A_Index 变量(其存在于各种类型的循环中) 的相关信息.</p>

<h2>相关</h2>
<p><a href="Loop.htm">Loop</a>, <a href="Break.htm">Break</a>, <a href="Continue.htm">Continue</a>, <a href="Block.htm">区块</a>, <a href="RegRead.htm">RegRead</a>, <a href="RegWrite.htm">RegWrite</a>, <a href="RegDelete.htm">RegDelete</a>, <a href="SetRegView.htm">SetRegView</a></p>

<h2>示例</h2>
<pre class="NoIndent"><em>; 示例: 删除用户输入的 Internet Explorer URL 历史:</em>
Loop, HKEY_CURRENT_USER, Software\Microsoft\Internet Explorer\TypedURLs
    RegDelete</pre>
<pre class="NoIndent"><em>; 示例: 有效的测试脚本:</em>
Loop, Reg, HKEY_CURRENT_USER\Software\Microsoft\Windows, KVR
{
    if A_LoopRegType = key
        value =
    else
    {
        RegRead, value
        if ErrorLevel
            value = *error*
    }
    MsgBox, 4, , %A_LoopRegName% = %value% (%A_LoopRegType%)`n`nContinue?
    IfMsgBox, NO, break
}</pre>
<pre class="NoIndent"><em>; 示例: 用于在整个注册表中
; 递归搜索特殊值的可运行示例.</em>
SetBatchLines -1  <em>; 让搜索以最快速度进行.</em>
RegSearchTarget = Notepad  <em>; 告知子程序搜索的目标.</em>
Gosub, RegSearch
return

RegSearch:
ContinueRegSearch = y
Loop, Reg, HKEY_LOCAL_MACHINE, KVR
{
    Gosub, CheckThisRegItem
    if ContinueRegSearch = n <em>; 这里告知我们要停止搜索.</em>
        return
}
Loop, Reg, HKEY_USERS, KVR
{
    Gosub, CheckThisRegItem
    if ContinueRegSearch = n <em>; 这里告知我们要停止搜索.</em>
        return
}
Loop, Reg, HKEY_CURRENT_CONFIG, KVR
{
    Gosub, CheckThisRegItem
    if ContinueRegSearch = n <em>; 这里告知我们要停止搜索.</em>
        return
}
<em>; 请注意: 我认为如果已经搜索了 HKEY_USERS, 那么可以不必搜索
; HKEY_CURRENT_USER.  同样地, 如果搜索了 HKEY_LOCAL_MACHINE,
; 那么可以不必搜索 HKEY_CLASSES_ROOT.</em>
return

CheckThisRegItem:
if A_LoopRegType = KEY  <em>; 如果您也想检查键名, 那么移除这两行.</em>
    return
RegRead, RegValue
if ErrorLevel
    return
IfInString, RegValue, %RegSearchTarget%
{
    MsgBox, 4, , The following match was found:`n%A_LoopRegKey%\%A_LoopRegSubKey%\%A_LoopRegName%`nValue = %RegValue%`n`nContinue?
    IfMsgBox, No
        ContinueRegSearch = n  <em>; 告知我们的调用者停止搜索.</em>
}
return</pre>

</body>
</html>